<?php
/**
 * 异步处理类
 * Created by PhpStorm.
 * User: zd
 * Date: 2019/3/25
 * Time: 17:12
 */

namespace app\server\controller;



use app\api\model\BehaviorType;
use app\api\model\CardBase;
use app\api\model\CardBrowse;
use app\api\model\Follow;
use app\api\model\Message;
use app\api\model\ThirdApp;
use app\api\model\UserWorkuser;
use app\api\model\WorkUser;
use app\api\service\BehaviorMessage;
use app\api\service\Card;
use app\api\service\DeliveryMessage;
use app\api\service\Rate;
use app\api\service\Statistics;
use app\common\lib\Queue;
use app\lib\enum\FollowStatusEnum;
use think\Cache;
use think\Config;

class Async{
    /**
     * 处理异步任务
     * @param $task_data
     * @return int
     */
    public function asyncTask($task_data){
        echo $task_data;
    }

    /**
     * 缓存聊天记录,并将聊天记录入库
     * @param $insertData
     * @return bool
     */
    public  function insertMessage($data=[],$message_data=[])
    {
        $messageData = $this->prepareMessageData($message_data,$data);
        $cache =  Cache::connect(Config::get('cache.redis'));
        //error_log(print_r($messageData, 1), 3, "./result.txt");
        if (isset($messageData['data']['from_wu_id'])){
            $str = $cache->handler()->get("message:tag:wid:".$messageData['wu_id'].":user:".$messageData['user_id']);
            if (empty($str)){
               $this->insertFollow($messageData['user_id'],$messageData['wu_id']);
               $cache->handler()->set("message:tag:wid:".$messageData['wu_id'].":user:".$messageData['user_id'],'tag',7200);//2小时过期
            }
        }
        Message::insertCord($messageData['data']);//聊天记录
        $status =  $this->cacheMessageList($messageData['wu_id'],$messageData['user_id'],$messageData['data']['create_time']);//缓存最新的用户聊天表
        $message = "message:wid:". $messageData['wu_id'].":user:".$messageData['user_id'].":info";
        $cache->handler()->set($message,json_encode($messageData['info']));//缓存未读消息
        self::cacheUnreadInfo($data['id'],$message_data);//缓存未读信息
        return $status;
    }

    /**
     * 成交率计算
     * @param $behavior
     * @param array $result
     * @param $wu_id
     * @return UserWorkuser
     */
    public function rate($behavior,$result=[],$wu_id){
        $type = BehaviorType::getCategory($behavior);
        $rate = new Rate($type->rate);
        $data = $rate->getRate($type->rate, $result);//计算成交率
        $user = UserWorkuser::getUserInfo($result['user_id'],$wu_id);
        if ($type->class == 1){
            $info['user_rate'] =  $rate->maxUserRate( $user,$data);
            $total_rate =  $info['user_rate'] + $user->product_rate + $user->web_rate;//总成交率
        }elseif ($type->class == 2){
            $info['product_rate'] =  $rate->maxProductRate($user,$data);
            $total_rate =  $info['product_rate'] + $user->user_rate + $user->web_rate;//总成交率
        }elseif ($type->class == 3){
            $info['web_rate'] =  $rate->maxWebRate($user,$data);
            $total_rate =  $info['web_rate'] + $user->user_rate + $user->product_rate;//总成交率
        }
        $info['rate'] =sprintf( "%.2f",($total_rate+ 5.00));
        $status = UserWorkuser::updateUserInfo($result['user_id'],$wu_id,$info);
        return $status;
    }

    /**
     * 用户浏览记录添加
     * @param $user_id
     * @param $wu_id
     * @return $this|string
     */
    public function insertBrowse($user_id,$wu_id){
        //访问量处理
        CardBase::browsing($wu_id);//访问量统计
        $status = '';
        $user['user'] = $user_id;
        $user['w_id'] = $wu_id;
        $browses = CardBrowse::getBrowse($wu_id);
        if ($browses != null){
            $users= $browses->column('user');
            $ids = $browses->column('id');
            if (!in_array($user_id,$users)){//不在记录里面才进行操作
                $status= CardBrowse::createBrowse($user);
                if (count($users)>5){
                    CardBrowse::deleteBrowse($ids[0]);//删除最开始的记录
                }
            }
        }else{
            CardBrowse::createBrowse($user);
        }
        return $status;
    }

    /**
     * 发送消息
     * @param $data
     * @param array $message_data
     * @return bool|mixed
     * @throws \think\exception\DbException
     */
    public function sendMessage($data,$message_data=[]){
        if ($message_data['user_type'] == 2) {
            //微信消息传递
            $result = self::sendWxMessage($data['id'], $message_data);
        }elseif ($message_data['user_type'] == 1){
            //企业微信传递
            $result = self::sendWorkWxMessage($data['id'],$message_data);

        }
        return $result;
    }

    /**
     * 读取队列信息并处理
     * @param $destination
     */
    public function readQueue($destination){
        $statistics = new Statistics();
        Queue::getInstance()->getMessageFormQueue($destination,array($statistics,'insertData',),$tag=1);//从第一次开始推送
    }

    /**
     * 发送微信消息
     * @param $client_id
     * @param $message
     * @param $message_data
     * @return bool
     */
    private static function sendWxMessage($id, array $message_data): bool
    {
        try{
            $w_id = $id;
            $user = WorkUser::get($w_id);
            $tplJumpPage = 'pages/card/chat/chat?w_id=' . $w_id;
            $message = new DeliveryMessage($user->t_id,'留言回复通知');
            $result = $message->sendUserMessage($message_data,$user->t_id ,$w_id, $tplJumpPage);
        }catch (\Exception $exception){
            $result =  false;
        }
        return $result;
    }

    /**
     * 发送企业消息
     * @param $id
     * @param $message_data
     * @return bool|mixed
     * @throws \think\exception\DbException
     */
    private static function sendWorkWxMessage( $id, array $message_data)
    {
        $user = WorkUser::get($message_data['to_client']);
        $thirdApp = ThirdApp::getUserInfo($user->t_id);
        $work = $thirdApp->work;
        $message = new BehaviorMessage();
        $result = $message->sendTextMessage($user, $work, $message_data);
        return $result;
    }

    /**
     * 准备入库信息
     * @param array $message_data
     * @param array $user
     * @return array
     */
    private function prepareMessageData( array $message_data, array $user): array
    {
        $wu_id = [];
        $user_id = [];
        $info = [];
        if ($message_data['user_type'] == 1) {
            $data['from_uid'] = $user['from_uid'];
            $data['to_wu_id'] = $message_data['to_client'];
            $wu_id = $data['to_wu_id'];
            $user_id = $data['from_uid'];
            $message_data['uid'] = $data['from_uid'];
            $info = $message_data;
            $info['time'] = date('Y-m-d H:i:s');
        } elseif ($message_data['user_type'] == 2) {
            $data['from_wu_id'] = $user['from_wu_id'];
            $data['to_uid'] = $message_data['to_client'];
            $wu_id = $data['from_wu_id'];
            $user_id = $data['to_uid'];
            $message_data['uid'] = $data['to_uid'];
            $info = $this->getCache($wu_id, $user_id, $message_data);//获取缓存
        }
        $data['timeid'] = $message_data['timeid'];
        $data['content'] = $message_data['content'];
        $data['create_time'] = time();
        $data['msg_type'] = $message_data['message_type'];
        return array('wu_id'=>$wu_id,'user_id'=> $user_id,'data'=>$data,'info'=>$info);
    }

    /**
     * 获取缓存
     * @param $wu_id
     * @param $user_id
     * @param array $message_data
     * @return array|mixed
     */
    private  function getCache($wu_id,$user_id,array $message_data){
        $result =  Cache::store('redis')->get("message:wid:". $wu_id.":user:".$user_id.":info");//获取缓存记录
        $result =  json_decode($result);
        if (empty($result)){
            $user = new Card();
            $info =  $user->getUserInfoById($user_id);
            $message_data['head_img'] = $info->avatar_url;
            $message_data['user_name'] = $info->nickname;
            $message_data['time'] = date('Y-m-d H:i:s');
            return $message_data;
        }else{
            $result->content = $message_data['content'];
            $result->message_type = $message_data['message_type'];
            $result->user_type = $message_data['user_type'];
            $result->time = date('Y-m-d H:i:s');
            return $result;
        }
    }
    /**
     * 缓存最新的用户聊天列表
     * @param $wu_id
     * @param $user_id
     * @param $score
     * @return bool
     */
    private function cacheMessageList($wu_id,$user_id,$score){
        try{
            $cache =  Cache::connect(Config::get('cache.redis'));
            $list = $cache->handler()->zRevRange("message:wid:".$wu_id.":user:list",0,-1);
            if (empty($list)){
                $cache->handler()->zadd("message:wid:".$wu_id.":user:list",$score,$user_id);
                //聊天记录用户入库
            }elseif(!in_array($user_id,$list)){
                $cache->handler()->zadd("message:wid:".$wu_id.":user:list",$score,$user_id);
            }
            //$cache->handler()->close();
            return true;
        }catch (\Exception $exception){
            //记录，报报警等其他操作
            return false;
        }
    }
    /**
     * 插入跟进行为信息
     * @param $user_id
     * @param $wu_id
     * @return $this
     */
    private function insertFollow($user_id,$wu_id){
        $info['user_id'] =$user_id;
        $info['wu_id'] = $wu_id;
        $info['url'] = request()->url();
        $info['weight'] = FollowStatusEnum::TALK;
        $info['content'] = '主动发起学员的对话';
        $follow = new Follow();
        $status =  $follow->createFollow($info);
        return $status;
    }
    /**
     * 缓存未读消息
     * @param $client_id
     * @param $message_data
     * @return bool
     */
    private static function cacheUnreadInfo($id,array $message_data){
        //缓存未读消息
        if ($message_data['user_type'] == 1){
            $score = time().rand(1,100);
            //缓存未读消息
            $result = self::cacheUnreadList($message_data['to_client'],$id,$score,json_encode($message_data),$message_data['user_type']);
        }elseif($message_data['user_type'] == 2){
            $score = time().rand(1,100);
            //缓存未读消息
            $result = self::cacheUnreadList($id,$message_data['to_client'],$score,json_encode($message_data),$message_data['user_type']);
        }
        return $result;
    }

    /**
     * 缓存未读消息
     * @param $wu_id
     * @param $user_id
     * @param $score
     * @return bool
     */
    private static function cacheUnreadList($wu_id,$user_id,$score,$content,$type){
        try{
            $cache =  Cache::connect(Config::get('cache.redis'));
            $list = $cache->handler()->zRevRange("message:wid:".$wu_id.":unread:user:".$user_id.":list",0,-1);
            if (empty($list)){
                $cache->handler()->zadd("message:wid:".$wu_id.":unread:user:".$user_id.":list:".$type,$score,$content);
            }elseif(!in_array($user_id,$list)){
                $cache->handler()->zadd("message:wid:".$wu_id.":unread:user:".$user_id.":list:".$type,$score,$content);
            }
            //$cache->handler()->close();
            return true;
        }catch (\Exception $exception){
            //记录，报报警等其他操作
            return false;
        }
    }

}